home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD ROM Paradise Collection 4
/
CD ROM Paradise Collection 4 1995 Nov.iso
/
clang
/
bueh16.zip
/
BUEH.C
next >
Wrap
C/C++ Source or Header
|
1994-08-26
|
4KB
|
156 lines
/****************************************************************************/
/* */
/* BUEH.C - Example of the Borland Unresolved Entry Hook function. */
/* */
/* The theory involved is as follows: If the loader finds a call to a */
/* function in User or Kernel that RTM doesn't implement, it looks for */
/* a function in your .EXE called BORLANDUNRESOLVEDENTRYHOOK. If this */
/* function (known as BUEH) is found, the module and ordinal or function */
/* name is passed. The BUEH is required to return the address of a */
/* function that will then be used for this entry. In other words, if */
/* the real function doesn't exist, you get a chance to redirect it to */
/* some other function that can simulate the functionality. */
/* */
/* Warning: If this file is not used as a seperate module that is linked */
/* as the first segment, then the data segment CANNOT be used. */
/* This example does not assume that the data segment will be */
/* availible. Therefore be careful when extending this code to */
/* handle additional unresolved functions. Don't assume that */
/* literal strings can be used from the main entry hook proc. */
/* */
/****************************************************************************/
#include <windows.h>
#include <stdio.h>
#include <dos.h>
#include <process.h>
// These two signatures are simply the first 4 chars in the module names.
// This is used so that we don't have to rely on the data segment being
// fixed up at this point.
#define KERNEL_SIG 0x4E52454BL
#define USER_SIG 0x52455355L
#ifdef __DPMI16__
void PrintStr (char *s, int mode)
{
char *p = s;
char c;
while (*p)
{
c = *p;
_DL = c;
_AH = 0x02;
geninterrupt (0x21);
p++;
}
if (mode == 1)
{
_DL = 10;
_AH = 0x02;
geninterrupt (0x21);
_DL = 13;
_AH = 0x02;
geninterrupt (0x21);
}
else
if (mode == 2)
{
_DL = 0x20;
_AH = 0x02;
geninterrupt (0x21);
}
}
char ToHexAscii (char c)
{
if (c < 0x0A)
return c | 0x30;
return 'A'+ (c - 0x0A);
}
void PrintByte (unsigned char num, int mode)
{
char str[3];
char un = num >> 4;
char ln = num & 0x0F;
str[0] = ToHexAscii (un);
str[1] = ToHexAscii (ln);
str[2] = 0;
PrintStr (str, mode);
}
void PrintNum (unsigned short num, int mode)
{
PrintByte ((num>>8), 0);
PrintByte ((num & 0x00FF), mode);
}
void __pascal __export BUEH_BigError (void)
{
printf ("\nNon fixed-up function called.\n");
exit (-1);
}
WORD __pascal _export BUEH_USER_GetFocus (void)
{
printf ("\nUSER.GetFocus called.\n");
return 0;
}
void __pascal _export BUEH_KERNEL_Yield (void)
{
printf ("\nKERNEL.Yield called.\n");
}
#pragma argsused
void * __pascal _export BorlandUnresolvedEntryHook (char *modname, int isOrd, char *Entry)
{
unsigned long far *lp = (unsigned long far *)modname;
int ord = 0;
if (isOrd)
ord = FP_OFF (Entry);
if (isOrd)
{
if (*lp == KERNEL_SIG)
{
switch (FP_OFF (Entry))
{
case 29: return BUEH_KERNEL_Yield;
}
}
else
if (*lp == USER_SIG)
{
switch (FP_OFF (Entry))
{
case 23: return BUEH_USER_GetFocus;
}
}
}
// If the function wasn't handled, then print out it's module and
// ordinal (in hex) for the user to see.
PrintStr (modname, 2);
if (isOrd)
PrintNum (ord, 1);
else
PrintStr (Entry, 1);
// and return the address of a function that will terminate the app. before
// it has a chance to cause a GP fault.
return BUEH_BigError;
}
#endif // __DPMI16__